1 /*
2 * Copyright (C) 2007 The Guava Authors
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 package com.google.common.collect;
18
19 import static com.google.common.base.Preconditions.checkNotNull;
20 import static com.google.common.collect.CollectPreconditions.checkNonnegative;
21 import static com.google.common.collect.CollectPreconditions.checkRemove;
22
23 import com.google.common.annotations.Beta;
24 import com.google.common.annotations.GwtCompatible;
25 import com.google.common.annotations.GwtIncompatible;
26 import com.google.common.base.Function;
27 import com.google.common.base.Predicate;
28 import com.google.common.base.Predicates;
29 import com.google.common.base.Supplier;
30 import com.google.common.collect.Maps.EntryTransformer;
31
32 import java.io.IOException;
33 import java.io.ObjectInputStream;
34 import java.io.ObjectOutputStream;
35 import java.io.Serializable;
36 import java.util.AbstractCollection;
37 import java.util.Collection;
38 import java.util.Collections;
39 import java.util.Comparator;
40 import java.util.HashSet;
41 import java.util.Iterator;
42 import java.util.List;
43 import java.util.Map;
44 import java.util.Map.Entry;
45 import java.util.NoSuchElementException;
46 import java.util.Set;
47 import java.util.SortedSet;
48
49 import javax.annotation.Nullable;
50
51 /**
52 * Provides static methods acting on or generating a {@code Multimap}.
53 *
54 * <p>See the Guava User Guide article on <a href=
55 * "http://code.google.com/p/guava-libraries/wiki/CollectionUtilitiesExplained#Multimaps">
56 * {@code Multimaps}</a>.
57 *
58 * @author Jared Levy
59 * @author Robert Konigsberg
60 * @author Mike Bostock
61 * @author Louis Wasserman
62 * @since 2.0 (imported from Google Collections Library)
63 */
64 @GwtCompatible(emulated = true)
65 public final class Multimaps {
66 private Multimaps() {}
67
68 /**
69 * Creates a new {@code Multimap} backed by {@code map}, whose internal value
70 * collections are generated by {@code factory}.
71 *
72 * <b>Warning: do not use</b> this method when the collections returned by
73 * {@code factory} implement either {@link List} or {@code Set}! Use the more
74 * specific method {@link #newListMultimap}, {@link #newSetMultimap} or {@link
75 * #newSortedSetMultimap} instead, to avoid very surprising behavior from
76 * {@link Multimap#equals}.
77 *
78 * <p>The {@code factory}-generated and {@code map} classes determine the
79 * multimap iteration order. They also specify the behavior of the
80 * {@code equals}, {@code hashCode}, and {@code toString} methods for the
81 * multimap and its returned views. However, the multimap's {@code get}
82 * method returns instances of a different class than {@code factory.get()}
83 * does.
84 *
85 * <p>The multimap is serializable if {@code map}, {@code factory}, the
86 * collections generated by {@code factory}, and the multimap contents are all
87 * serializable.
88 *
89 * <p>The multimap is not threadsafe when any concurrent operations update the
90 * multimap, even if {@code map} and the instances generated by
91 * {@code factory} are. Concurrent read operations will work correctly. To
92 * allow concurrent update operations, wrap the multimap with a call to
93 * {@link #synchronizedMultimap}.
94 *
95 * <p>Call this method only when the simpler methods
96 * {@link ArrayListMultimap#create()}, {@link HashMultimap#create()},
97 * {@link LinkedHashMultimap#create()}, {@link LinkedListMultimap#create()},
98 * {@link TreeMultimap#create()}, and
99 * {@link TreeMultimap#create(Comparator, Comparator)} won't suffice.
100 *
101 * <p>Note: the multimap assumes complete ownership over of {@code map} and
102 * the collections returned by {@code factory}. Those objects should not be
103 * manually updated and they should not use soft, weak, or phantom references.
104 *
105 * @param map place to store the mapping from each key to its corresponding
106 * values
107 * @param factory supplier of new, empty collections that will each hold all
108 * values for a given key
109 * @throws IllegalArgumentException if {@code map} is not empty
110 */
111 public static <K, V> Multimap<K, V> newMultimap(Map<K, Collection<V>> map,
112 final Supplier<? extends Collection<V>> factory) {
113 return new CustomMultimap<K, V>(map, factory);
114 }
115
116 private static class CustomMultimap<K, V> extends AbstractMapBasedMultimap<K, V> {
117 transient Supplier<? extends Collection<V>> factory;
118
119 CustomMultimap(Map<K, Collection<V>> map,
120 Supplier<? extends Collection<V>> factory) {
121 super(map);
122 this.factory = checkNotNull(factory);
123 }
124
125 @Override protected Collection<V> createCollection() {
126 return factory.get();
127 }
128
129 // can't use Serialization writeMultimap and populateMultimap methods since
130 // there's no way to generate the empty backing map.
131
132 /** @serialData the factory and the backing map */
133 @GwtIncompatible("java.io.ObjectOutputStream")
134 private void writeObject(ObjectOutputStream stream) throws IOException {
135 stream.defaultWriteObject();
136 stream.writeObject(factory);
137 stream.writeObject(backingMap());
138 }
139
140 @GwtIncompatible("java.io.ObjectInputStream")
141 @SuppressWarnings("unchecked") // reading data stored by writeObject
142 private void readObject(ObjectInputStream stream)
143 throws IOException, ClassNotFoundException {
144 stream.defaultReadObject();
145 factory = (Supplier<? extends Collection<V>>) stream.readObject();
146 Map<K, Collection<V>> map = (Map<K, Collection<V>>) stream.readObject();
147 setMap(map);
148 }
149
150 @GwtIncompatible("java serialization not supported")
151 private static final long serialVersionUID = 0;
152 }
153
154 /**
155 * Creates a new {@code ListMultimap} that uses the provided map and factory.
156 * It can generate a multimap based on arbitrary {@link Map} and {@link List}
157 * classes.
158 *
159 * <p>The {@code factory}-generated and {@code map} classes determine the
160 * multimap iteration order. They also specify the behavior of the
161 * {@code equals}, {@code hashCode}, and {@code toString} methods for the
162 * multimap and its returned views. The multimap's {@code get}, {@code
163 * removeAll}, and {@code replaceValues} methods return {@code RandomAccess}
164 * lists if the factory does. However, the multimap's {@code get} method
165 * returns instances of a different class than does {@code factory.get()}.
166 *
167 * <p>The multimap is serializable if {@code map}, {@code factory}, the
168 * lists generated by {@code factory}, and the multimap contents are all
169 * serializable.
170 *
171 * <p>The multimap is not threadsafe when any concurrent operations update the
172 * multimap, even if {@code map} and the instances generated by
173 * {@code factory} are. Concurrent read operations will work correctly. To
174 * allow concurrent update operations, wrap the multimap with a call to
175 * {@link #synchronizedListMultimap}.
176 *
177 * <p>Call this method only when the simpler methods
178 * {@link ArrayListMultimap#create()} and {@link LinkedListMultimap#create()}
179 * won't suffice.
180 *
181 * <p>Note: the multimap assumes complete ownership over of {@code map} and
182 * the lists returned by {@code factory}. Those objects should not be manually
183 * updated, they should be empty when provided, and they should not use soft,
184 * weak, or phantom references.
185 *
186 * @param map place to store the mapping from each key to its corresponding
187 * values
188 * @param factory supplier of new, empty lists that will each hold all values
189 * for a given key
190 * @throws IllegalArgumentException if {@code map} is not empty
191 */
192 public static <K, V> ListMultimap<K, V> newListMultimap(
193 Map<K, Collection<V>> map, final Supplier<? extends List<V>> factory) {
194 return new CustomListMultimap<K, V>(map, factory);
195 }
196
197 private static class CustomListMultimap<K, V>
198 extends AbstractListMultimap<K, V> {
199 transient Supplier<? extends List<V>> factory;
200
201 CustomListMultimap(Map<K, Collection<V>> map,
202 Supplier<? extends List<V>> factory) {
203 super(map);
204 this.factory = checkNotNull(factory);
205 }
206
207 @Override protected List<V> createCollection() {
208 return factory.get();
209 }
210
211 /** @serialData the factory and the backing map */
212 @GwtIncompatible("java.io.ObjectOutputStream")
213 private void writeObject(ObjectOutputStream stream) throws IOException {
214 stream.defaultWriteObject();
215 stream.writeObject(factory);
216 stream.writeObject(backingMap());
217 }
218
219 @GwtIncompatible("java.io.ObjectInputStream")
220 @SuppressWarnings("unchecked") // reading data stored by writeObject
221 private void readObject(ObjectInputStream stream)
222 throws IOException, ClassNotFoundException {
223 stream.defaultReadObject();
224 factory = (Supplier<? extends List<V>>) stream.readObject();
225 Map<K, Collection<V>> map = (Map<K, Collection<V>>) stream.readObject();
226 setMap(map);
227 }
228
229 @GwtIncompatible("java serialization not supported")
230 private static final long serialVersionUID = 0;
231 }
232
233 /**
234 * Creates a new {@code SetMultimap} that uses the provided map and factory.
235 * It can generate a multimap based on arbitrary {@link Map} and {@link Set}
236 * classes.
237 *
238 * <p>The {@code factory}-generated and {@code map} classes determine the
239 * multimap iteration order. They also specify the behavior of the
240 * {@code equals}, {@code hashCode}, and {@code toString} methods for the
241 * multimap and its returned views. However, the multimap's {@code get}
242 * method returns instances of a different class than {@code factory.get()}
243 * does.
244 *
245 * <p>The multimap is serializable if {@code map}, {@code factory}, the
246 * sets generated by {@code factory}, and the multimap contents are all
247 * serializable.
248 *
249 * <p>The multimap is not threadsafe when any concurrent operations update the
250 * multimap, even if {@code map} and the instances generated by
251 * {@code factory} are. Concurrent read operations will work correctly. To
252 * allow concurrent update operations, wrap the multimap with a call to
253 * {@link #synchronizedSetMultimap}.
254 *
255 * <p>Call this method only when the simpler methods
256 * {@link HashMultimap#create()}, {@link LinkedHashMultimap#create()},
257 * {@link TreeMultimap#create()}, and
258 * {@link TreeMultimap#create(Comparator, Comparator)} won't suffice.
259 *
260 * <p>Note: the multimap assumes complete ownership over of {@code map} and
261 * the sets returned by {@code factory}. Those objects should not be manually
262 * updated and they should not use soft, weak, or phantom references.
263 *
264 * @param map place to store the mapping from each key to its corresponding
265 * values
266 * @param factory supplier of new, empty sets that will each hold all values
267 * for a given key
268 * @throws IllegalArgumentException if {@code map} is not empty
269 */
270 public static <K, V> SetMultimap<K, V> newSetMultimap(
271 Map<K, Collection<V>> map, final Supplier<? extends Set<V>> factory) {
272 return new CustomSetMultimap<K, V>(map, factory);
273 }
274
275 private static class CustomSetMultimap<K, V>
276 extends AbstractSetMultimap<K, V> {
277 transient Supplier<? extends Set<V>> factory;
278
279 CustomSetMultimap(Map<K, Collection<V>> map,
280 Supplier<? extends Set<V>> factory) {
281 super(map);
282 this.factory = checkNotNull(factory);
283 }
284
285 @Override protected Set<V> createCollection() {
286 return factory.get();
287 }
288
289 /** @serialData the factory and the backing map */
290 @GwtIncompatible("java.io.ObjectOutputStream")
291 private void writeObject(ObjectOutputStream stream) throws IOException {
292 stream.defaultWriteObject();
293 stream.writeObject(factory);
294 stream.writeObject(backingMap());
295 }
296
297 @GwtIncompatible("java.io.ObjectInputStream")
298 @SuppressWarnings("unchecked") // reading data stored by writeObject
299 private void readObject(ObjectInputStream stream)
300 throws IOException, ClassNotFoundException {
301 stream.defaultReadObject();
302 factory = (Supplier<? extends Set<V>>) stream.readObject();
303 Map<K, Collection<V>> map = (Map<K, Collection<V>>) stream.readObject();
304 setMap(map);
305 }
306
307 @GwtIncompatible("not needed in emulated source")
308 private static final long serialVersionUID = 0;
309 }
310
311 /**
312 * Creates a new {@code SortedSetMultimap} that uses the provided map and
313 * factory. It can generate a multimap based on arbitrary {@link Map} and
314 * {@link SortedSet} classes.
315 *
316 * <p>The {@code factory}-generated and {@code map} classes determine the
317 * multimap iteration order. They also specify the behavior of the
318 * {@code equals}, {@code hashCode}, and {@code toString} methods for the
319 * multimap and its returned views. However, the multimap's {@code get}
320 * method returns instances of a different class than {@code factory.get()}
321 * does.
322 *
323 * <p>The multimap is serializable if {@code map}, {@code factory}, the
324 * sets generated by {@code factory}, and the multimap contents are all
325 * serializable.
326 *
327 * <p>The multimap is not threadsafe when any concurrent operations update the
328 * multimap, even if {@code map} and the instances generated by
329 * {@code factory} are. Concurrent read operations will work correctly. To
330 * allow concurrent update operations, wrap the multimap with a call to
331 * {@link #synchronizedSortedSetMultimap}.
332 *
333 * <p>Call this method only when the simpler methods
334 * {@link TreeMultimap#create()} and
335 * {@link TreeMultimap#create(Comparator, Comparator)} won't suffice.
336 *
337 * <p>Note: the multimap assumes complete ownership over of {@code map} and
338 * the sets returned by {@code factory}. Those objects should not be manually
339 * updated and they should not use soft, weak, or phantom references.
340 *
341 * @param map place to store the mapping from each key to its corresponding
342 * values
343 * @param factory supplier of new, empty sorted sets that will each hold
344 * all values for a given key
345 * @throws IllegalArgumentException if {@code map} is not empty
346 */
347 public static <K, V> SortedSetMultimap<K, V> newSortedSetMultimap(
348 Map<K, Collection<V>> map,
349 final Supplier<? extends SortedSet<V>> factory) {
350 return new CustomSortedSetMultimap<K, V>(map, factory);
351 }
352
353 private static class CustomSortedSetMultimap<K, V>
354 extends AbstractSortedSetMultimap<K, V> {
355 transient Supplier<? extends SortedSet<V>> factory;
356 transient Comparator<? super V> valueComparator;
357
358 CustomSortedSetMultimap(Map<K, Collection<V>> map,
359 Supplier<? extends SortedSet<V>> factory) {
360 super(map);
361 this.factory = checkNotNull(factory);
362 valueComparator = factory.get().comparator();
363 }
364
365 @Override protected SortedSet<V> createCollection() {
366 return factory.get();
367 }
368
369 @Override public Comparator<? super V> valueComparator() {
370 return valueComparator;
371 }
372
373 /** @serialData the factory and the backing map */
374 @GwtIncompatible("java.io.ObjectOutputStream")
375 private void writeObject(ObjectOutputStream stream) throws IOException {
376 stream.defaultWriteObject();
377 stream.writeObject(factory);
378 stream.writeObject(backingMap());
379 }
380
381 @GwtIncompatible("java.io.ObjectInputStream")
382 @SuppressWarnings("unchecked") // reading data stored by writeObject
383 private void readObject(ObjectInputStream stream)
384 throws IOException, ClassNotFoundException {
385 stream.defaultReadObject();
386 factory = (Supplier<? extends SortedSet<V>>) stream.readObject();
387 valueComparator = factory.get().comparator();
388 Map<K, Collection<V>> map = (Map<K, Collection<V>>) stream.readObject();
389 setMap(map);
390 }
391
392 @GwtIncompatible("not needed in emulated source")
393 private static final long serialVersionUID = 0;
394 }
395
396 /**
397 * Copies each key-value mapping in {@code source} into {@code dest}, with
398 * its key and value reversed.
399 *
400 * <p>If {@code source} is an {@link ImmutableMultimap}, consider using
401 * {@link ImmutableMultimap#inverse} instead.
402 *
403 * @param source any multimap
404 * @param dest the multimap to copy into; usually empty
405 * @return {@code dest}
406 */
407 public static <K, V, M extends Multimap<K, V>> M invertFrom(
408 Multimap<? extends V, ? extends K> source, M dest) {
409 checkNotNull(dest);
410 for (Map.Entry<? extends V, ? extends K> entry : source.entries()) {
411 dest.put(entry.getValue(), entry.getKey());
412 }
413 return dest;
414 }
415
416 /**
417 * Returns a synchronized (thread-safe) multimap backed by the specified
418 * multimap. In order to guarantee serial access, it is critical that
419 * <b>all</b> access to the backing multimap is accomplished through the
420 * returned multimap.
421 *
422 * <p>It is imperative that the user manually synchronize on the returned
423 * multimap when accessing any of its collection views: <pre> {@code
424 *
425 * Multimap<K, V> multimap = Multimaps.synchronizedMultimap(
426 * HashMultimap.<K, V>create());
427 * ...
428 * Collection<V> values = multimap.get(key); // Needn't be in synchronized block
429 * ...
430 * synchronized (multimap) { // Synchronizing on multimap, not values!
431 * Iterator<V> i = values.iterator(); // Must be in synchronized block
432 * while (i.hasNext()) {
433 * foo(i.next());
434 * }
435 * }}</pre>
436 *
437 * <p>Failure to follow this advice may result in non-deterministic behavior.
438 *
439 * <p>Note that the generated multimap's {@link Multimap#removeAll} and
440 * {@link Multimap#replaceValues} methods return collections that aren't
441 * synchronized.
442 *
443 * <p>The returned multimap will be serializable if the specified multimap is
444 * serializable.
445 *
446 * @param multimap the multimap to be wrapped in a synchronized view
447 * @return a synchronized view of the specified multimap
448 */
449 public static <K, V> Multimap<K, V> synchronizedMultimap(
450 Multimap<K, V> multimap) {
451 return Synchronized.multimap(multimap, null);
452 }
453
454 /**
455 * Returns an unmodifiable view of the specified multimap. Query operations on
456 * the returned multimap "read through" to the specified multimap, and
457 * attempts to modify the returned multimap, either directly or through the
458 * multimap's views, result in an {@code UnsupportedOperationException}.
459 *
460 * <p>Note that the generated multimap's {@link Multimap#removeAll} and
461 * {@link Multimap#replaceValues} methods return collections that are
462 * modifiable.
463 *
464 * <p>The returned multimap will be serializable if the specified multimap is
465 * serializable.
466 *
467 * @param delegate the multimap for which an unmodifiable view is to be
468 * returned
469 * @return an unmodifiable view of the specified multimap
470 */
471 public static <K, V> Multimap<K, V> unmodifiableMultimap(
472 Multimap<K, V> delegate) {
473 if (delegate instanceof UnmodifiableMultimap ||
474 delegate instanceof ImmutableMultimap) {
475 return delegate;
476 }
477 return new UnmodifiableMultimap<K, V>(delegate);
478 }
479
480 /**
481 * Simply returns its argument.
482 *
483 * @deprecated no need to use this
484 * @since 10.0
485 */
486 @Deprecated public static <K, V> Multimap<K, V> unmodifiableMultimap(
487 ImmutableMultimap<K, V> delegate) {
488 return checkNotNull(delegate);
489 }
490
491 private static class UnmodifiableMultimap<K, V>
492 extends ForwardingMultimap<K, V> implements Serializable {
493 final Multimap<K, V> delegate;
494 transient Collection<Entry<K, V>> entries;
495 transient Multiset<K> keys;
496 transient Set<K> keySet;
497 transient Collection<V> values;
498 transient Map<K, Collection<V>> map;
499
500 UnmodifiableMultimap(final Multimap<K, V> delegate) {
501 this.delegate = checkNotNull(delegate);
502 }
503
504 @Override protected Multimap<K, V> delegate() {
505 return delegate;
506 }
507
508 @Override public void clear() {
509 throw new UnsupportedOperationException();
510 }
511
512 @Override public Map<K, Collection<V>> asMap() {
513 Map<K, Collection<V>> result = map;
514 if (result == null) {
515 result = map = Collections.unmodifiableMap(
516 Maps.transformValues(delegate.asMap(), new Function<Collection<V>, Collection<V>>() {
517 @Override
518 public Collection<V> apply(Collection<V> collection) {
519 return unmodifiableValueCollection(collection);
520 }
521 }));
522 }
523 return result;
524 }
525
526 @Override public Collection<Entry<K, V>> entries() {
527 Collection<Entry<K, V>> result = entries;
528 if (result == null) {
529 entries = result = unmodifiableEntries(delegate.entries());
530 }
531 return result;
532 }
533
534 @Override public Collection<V> get(K key) {
535 return unmodifiableValueCollection(delegate.get(key));
536 }
537
538 @Override public Multiset<K> keys() {
539 Multiset<K> result = keys;
540 if (result == null) {
541 keys = result = Multisets.unmodifiableMultiset(delegate.keys());
542 }
543 return result;
544 }
545
546 @Override public Set<K> keySet() {
547 Set<K> result = keySet;
548 if (result == null) {
549 keySet = result = Collections.unmodifiableSet(delegate.keySet());
550 }
551 return result;
552 }
553
554 @Override public boolean put(K key, V value) {
555 throw new UnsupportedOperationException();
556 }
557
558 @Override public boolean putAll(K key, Iterable<? extends V> values) {
559 throw new UnsupportedOperationException();
560 }
561
562 @Override
563 public boolean putAll(Multimap<? extends K, ? extends V> multimap) {
564 throw new UnsupportedOperationException();
565 }
566
567 @Override public boolean remove(Object key, Object value) {
568 throw new UnsupportedOperationException();
569 }
570
571 @Override public Collection<V> removeAll(Object key) {
572 throw new UnsupportedOperationException();
573 }
574
575 @Override public Collection<V> replaceValues(
576 K key, Iterable<? extends V> values) {
577 throw new UnsupportedOperationException();
578 }
579
580 @Override public Collection<V> values() {
581 Collection<V> result = values;
582 if (result == null) {
583 values = result = Collections.unmodifiableCollection(delegate.values());
584 }
585 return result;
586 }
587
588 private static final long serialVersionUID = 0;
589 }
590
591 private static class UnmodifiableListMultimap<K, V>
592 extends UnmodifiableMultimap<K, V> implements ListMultimap<K, V> {
593 UnmodifiableListMultimap(ListMultimap<K, V> delegate) {
594 super(delegate);
595 }
596 @Override public ListMultimap<K, V> delegate() {
597 return (ListMultimap<K, V>) super.delegate();
598 }
599 @Override public List<V> get(K key) {
600 return Collections.unmodifiableList(delegate().get(key));
601 }
602 @Override public List<V> removeAll(Object key) {
603 throw new UnsupportedOperationException();
604 }
605 @Override public List<V> replaceValues(
606 K key, Iterable<? extends V> values) {
607 throw new UnsupportedOperationException();
608 }
609 private static final long serialVersionUID = 0;
610 }
611
612 private static class UnmodifiableSetMultimap<K, V>
613 extends UnmodifiableMultimap<K, V> implements SetMultimap<K, V> {
614 UnmodifiableSetMultimap(SetMultimap<K, V> delegate) {
615 super(delegate);
616 }
617 @Override public SetMultimap<K, V> delegate() {
618 return (SetMultimap<K, V>) super.delegate();
619 }
620 @Override public Set<V> get(K key) {
621 /*
622 * Note that this doesn't return a SortedSet when delegate is a
623 * SortedSetMultiset, unlike (SortedSet<V>) super.get().
624 */
625 return Collections.unmodifiableSet(delegate().get(key));
626 }
627 @Override public Set<Map.Entry<K, V>> entries() {
628 return Maps.unmodifiableEntrySet(delegate().entries());
629 }
630 @Override public Set<V> removeAll(Object key) {
631 throw new UnsupportedOperationException();
632 }
633 @Override public Set<V> replaceValues(
634 K key, Iterable<? extends V> values) {
635 throw new UnsupportedOperationException();
636 }
637 private static final long serialVersionUID = 0;
638 }
639
640 private static class UnmodifiableSortedSetMultimap<K, V>
641 extends UnmodifiableSetMultimap<K, V> implements SortedSetMultimap<K, V> {
642 UnmodifiableSortedSetMultimap(SortedSetMultimap<K, V> delegate) {
643 super(delegate);
644 }
645 @Override public SortedSetMultimap<K, V> delegate() {
646 return (SortedSetMultimap<K, V>) super.delegate();
647 }
648 @Override public SortedSet<V> get(K key) {
649 return Collections.unmodifiableSortedSet(delegate().get(key));
650 }
651 @Override public SortedSet<V> removeAll(Object key) {
652 throw new UnsupportedOperationException();
653 }
654 @Override public SortedSet<V> replaceValues(
655 K key, Iterable<? extends V> values) {
656 throw new UnsupportedOperationException();
657 }
658 @Override
659 public Comparator<? super V> valueComparator() {
660 return delegate().valueComparator();
661 }
662 private static final long serialVersionUID = 0;
663 }
664
665 /**
666 * Returns a synchronized (thread-safe) {@code SetMultimap} backed by the
667 * specified multimap.
668 *
669 * <p>You must follow the warnings described in {@link #synchronizedMultimap}.
670 *
671 * <p>The returned multimap will be serializable if the specified multimap is
672 * serializable.
673 *
674 * @param multimap the multimap to be wrapped
675 * @return a synchronized view of the specified multimap
676 */
677 public static <K, V> SetMultimap<K, V> synchronizedSetMultimap(
678 SetMultimap<K, V> multimap) {
679 return Synchronized.setMultimap(multimap, null);
680 }
681
682 /**
683 * Returns an unmodifiable view of the specified {@code SetMultimap}. Query
684 * operations on the returned multimap "read through" to the specified
685 * multimap, and attempts to modify the returned multimap, either directly or
686 * through the multimap's views, result in an
687 * {@code UnsupportedOperationException}.
688 *
689 * <p>Note that the generated multimap's {@link Multimap#removeAll} and
690 * {@link Multimap#replaceValues} methods return collections that are
691 * modifiable.
692 *
693 * <p>The returned multimap will be serializable if the specified multimap is
694 * serializable.
695 *
696 * @param delegate the multimap for which an unmodifiable view is to be
697 * returned
698 * @return an unmodifiable view of the specified multimap
699 */
700 public static <K, V> SetMultimap<K, V> unmodifiableSetMultimap(
701 SetMultimap<K, V> delegate) {
702 if (delegate instanceof UnmodifiableSetMultimap ||
703 delegate instanceof ImmutableSetMultimap) {
704 return delegate;
705 }
706 return new UnmodifiableSetMultimap<K, V>(delegate);
707 }
708
709 /**
710 * Simply returns its argument.
711 *
712 * @deprecated no need to use this
713 * @since 10.0
714 */
715 @Deprecated public static <K, V> SetMultimap<K, V> unmodifiableSetMultimap(
716 ImmutableSetMultimap<K, V> delegate) {
717 return checkNotNull(delegate);
718 }
719
720 /**
721 * Returns a synchronized (thread-safe) {@code SortedSetMultimap} backed by
722 * the specified multimap.
723 *
724 * <p>You must follow the warnings described in {@link #synchronizedMultimap}.
725 *
726 * <p>The returned multimap will be serializable if the specified multimap is
727 * serializable.
728 *
729 * @param multimap the multimap to be wrapped
730 * @return a synchronized view of the specified multimap
731 */
732 public static <K, V> SortedSetMultimap<K, V>
733 synchronizedSortedSetMultimap(SortedSetMultimap<K, V> multimap) {
734 return Synchronized.sortedSetMultimap(multimap, null);
735 }
736
737 /**
738 * Returns an unmodifiable view of the specified {@code SortedSetMultimap}.
739 * Query operations on the returned multimap "read through" to the specified
740 * multimap, and attempts to modify the returned multimap, either directly or
741 * through the multimap's views, result in an
742 * {@code UnsupportedOperationException}.
743 *
744 * <p>Note that the generated multimap's {@link Multimap#removeAll} and
745 * {@link Multimap#replaceValues} methods return collections that are
746 * modifiable.
747 *
748 * <p>The returned multimap will be serializable if the specified multimap is
749 * serializable.
750 *
751 * @param delegate the multimap for which an unmodifiable view is to be
752 * returned
753 * @return an unmodifiable view of the specified multimap
754 */
755 public static <K, V> SortedSetMultimap<K, V> unmodifiableSortedSetMultimap(
756 SortedSetMultimap<K, V> delegate) {
757 if (delegate instanceof UnmodifiableSortedSetMultimap) {
758 return delegate;
759 }
760 return new UnmodifiableSortedSetMultimap<K, V>(delegate);
761 }
762
763 /**
764 * Returns a synchronized (thread-safe) {@code ListMultimap} backed by the
765 * specified multimap.
766 *
767 * <p>You must follow the warnings described in {@link #synchronizedMultimap}.
768 *
769 * @param multimap the multimap to be wrapped
770 * @return a synchronized view of the specified multimap
771 */
772 public static <K, V> ListMultimap<K, V> synchronizedListMultimap(
773 ListMultimap<K, V> multimap) {
774 return Synchronized.listMultimap(multimap, null);
775 }
776
777 /**
778 * Returns an unmodifiable view of the specified {@code ListMultimap}. Query
779 * operations on the returned multimap "read through" to the specified
780 * multimap, and attempts to modify the returned multimap, either directly or
781 * through the multimap's views, result in an
782 * {@code UnsupportedOperationException}.
783 *
784 * <p>Note that the generated multimap's {@link Multimap#removeAll} and
785 * {@link Multimap#replaceValues} methods return collections that are
786 * modifiable.
787 *
788 * <p>The returned multimap will be serializable if the specified multimap is
789 * serializable.
790 *
791 * @param delegate the multimap for which an unmodifiable view is to be
792 * returned
793 * @return an unmodifiable view of the specified multimap
794 */
795 public static <K, V> ListMultimap<K, V> unmodifiableListMultimap(
796 ListMultimap<K, V> delegate) {
797 if (delegate instanceof UnmodifiableListMultimap ||
798 delegate instanceof ImmutableListMultimap) {
799 return delegate;
800 }
801 return new UnmodifiableListMultimap<K, V>(delegate);
802 }
803
804 /**
805 * Simply returns its argument.
806 *
807 * @deprecated no need to use this
808 * @since 10.0
809 */
810 @Deprecated public static <K, V> ListMultimap<K, V> unmodifiableListMultimap(
811 ImmutableListMultimap<K, V> delegate) {
812 return checkNotNull(delegate);
813 }
814
815 /**
816 * Returns an unmodifiable view of the specified collection, preserving the
817 * interface for instances of {@code SortedSet}, {@code Set}, {@code List} and
818 * {@code Collection}, in that order of preference.
819 *
820 * @param collection the collection for which to return an unmodifiable view
821 * @return an unmodifiable view of the collection
822 */
823 private static <V> Collection<V> unmodifiableValueCollection(
824 Collection<V> collection) {
825 if (collection instanceof SortedSet) {
826 return Collections.unmodifiableSortedSet((SortedSet<V>) collection);
827 } else if (collection instanceof Set) {
828 return Collections.unmodifiableSet((Set<V>) collection);
829 } else if (collection instanceof List) {
830 return Collections.unmodifiableList((List<V>) collection);
831 }
832 return Collections.unmodifiableCollection(collection);
833 }
834
835 /**
836 * Returns an unmodifiable view of the specified collection of entries. The
837 * {@link Entry#setValue} operation throws an {@link
838 * UnsupportedOperationException}. If the specified collection is a {@code
839 * Set}, the returned collection is also a {@code Set}.
840 *
841 * @param entries the entries for which to return an unmodifiable view
842 * @return an unmodifiable view of the entries
843 */
844 private static <K, V> Collection<Entry<K, V>> unmodifiableEntries(
845 Collection<Entry<K, V>> entries) {
846 if (entries instanceof Set) {
847 return Maps.unmodifiableEntrySet((Set<Entry<K, V>>) entries);
848 }
849 return new Maps.UnmodifiableEntries<K, V>(
850 Collections.unmodifiableCollection(entries));
851 }
852
853 /**
854 * Returns {@link ListMultimap#asMap multimap.asMap()}, with its type
855 * corrected from {@code Map<K, Collection<V>>} to {@code Map<K, List<V>>}.
856 *
857 * @since 15.0
858 */
859 @Beta
860 @SuppressWarnings("unchecked")
861 // safe by specification of ListMultimap.asMap()
862 public static <K, V> Map<K, List<V>> asMap(ListMultimap<K, V> multimap) {
863 return (Map<K, List<V>>) (Map<K, ?>) multimap.asMap();
864 }
865
866 /**
867 * Returns {@link SetMultimap#asMap multimap.asMap()}, with its type corrected
868 * from {@code Map<K, Collection<V>>} to {@code Map<K, Set<V>>}.
869 *
870 * @since 15.0
871 */
872 @Beta
873 @SuppressWarnings("unchecked")
874 // safe by specification of SetMultimap.asMap()
875 public static <K, V> Map<K, Set<V>> asMap(SetMultimap<K, V> multimap) {
876 return (Map<K, Set<V>>) (Map<K, ?>) multimap.asMap();
877 }
878
879 /**
880 * Returns {@link SortedSetMultimap#asMap multimap.asMap()}, with its type
881 * corrected from {@code Map<K, Collection<V>>} to
882 * {@code Map<K, SortedSet<V>>}.
883 *
884 * @since 15.0
885 */
886 @Beta
887 @SuppressWarnings("unchecked")
888 // safe by specification of SortedSetMultimap.asMap()
889 public static <K, V> Map<K, SortedSet<V>> asMap(
890 SortedSetMultimap<K, V> multimap) {
891 return (Map<K, SortedSet<V>>) (Map<K, ?>) multimap.asMap();
892 }
893
894 /**
895 * Returns {@link Multimap#asMap multimap.asMap()}. This is provided for
896 * parity with the other more strongly-typed {@code asMap()} implementations.
897 *
898 * @since 15.0
899 */
900 @Beta
901 public static <K, V> Map<K, Collection<V>> asMap(Multimap<K, V> multimap) {
902 return multimap.asMap();
903 }
904
905 /**
906 * Returns a multimap view of the specified map. The multimap is backed by the
907 * map, so changes to the map are reflected in the multimap, and vice versa.
908 * If the map is modified while an iteration over one of the multimap's
909 * collection views is in progress (except through the iterator's own {@code
910 * remove} operation, or through the {@code setValue} operation on a map entry
911 * returned by the iterator), the results of the iteration are undefined.
912 *
913 * <p>The multimap supports mapping removal, which removes the corresponding
914 * mapping from the map. It does not support any operations which might add
915 * mappings, such as {@code put}, {@code putAll} or {@code replaceValues}.
916 *
917 * <p>The returned multimap will be serializable if the specified map is
918 * serializable.
919 *
920 * @param map the backing map for the returned multimap view
921 */
922 public static <K, V> SetMultimap<K, V> forMap(Map<K, V> map) {
923 return new MapMultimap<K, V>(map);
924 }
925
926 /** @see Multimaps#forMap */
927 private static class MapMultimap<K, V>
928 extends AbstractMultimap<K, V> implements SetMultimap<K, V>, Serializable {
929 final Map<K, V> map;
930
931 MapMultimap(Map<K, V> map) {
932 this.map = checkNotNull(map);
933 }
934
935 @Override
936 public int size() {
937 return map.size();
938 }
939
940 @Override
941 public boolean containsKey(Object key) {
942 return map.containsKey(key);
943 }
944
945 @Override
946 public boolean containsValue(Object value) {
947 return map.containsValue(value);
948 }
949
950 @Override
951 public boolean containsEntry(Object key, Object value) {
952 return map.entrySet().contains(Maps.immutableEntry(key, value));
953 }
954
955 @Override
956 public Set<V> get(final K key) {
957 return new Sets.ImprovedAbstractSet<V>() {
958 @Override public Iterator<V> iterator() {
959 return new Iterator<V>() {
960 int i;
961
962 @Override
963 public boolean hasNext() {
964 return (i == 0) && map.containsKey(key);
965 }
966
967 @Override
968 public V next() {
969 if (!hasNext()) {
970 throw new NoSuchElementException();
971 }
972 i++;
973 return map.get(key);
974 }
975
976 @Override
977 public void remove() {
978 checkRemove(i == 1);
979 i = -1;
980 map.remove(key);
981 }
982 };
983 }
984
985 @Override public int size() {
986 return map.containsKey(key) ? 1 : 0;
987 }
988 };
989 }
990
991 @Override
992 public boolean put(K key, V value) {
993 throw new UnsupportedOperationException();
994 }
995
996 @Override
997 public boolean putAll(K key, Iterable<? extends V> values) {
998 throw new UnsupportedOperationException();
999 }
1000
1001 @Override
1002 public boolean putAll(Multimap<? extends K, ? extends V> multimap) {
1003 throw new UnsupportedOperationException();
1004 }
1005
1006 @Override
1007 public Set<V> replaceValues(K key, Iterable<? extends V> values) {
1008 throw new UnsupportedOperationException();
1009 }
1010
1011 @Override
1012 public boolean remove(Object key, Object value) {
1013 return map.entrySet().remove(Maps.immutableEntry(key, value));
1014 }
1015
1016 @Override
1017 public Set<V> removeAll(Object key) {
1018 Set<V> values = new HashSet<V>(2);
1019 if (!map.containsKey(key)) {
1020 return values;
1021 }
1022 values.add(map.remove(key));
1023 return values;
1024 }
1025
1026 @Override
1027 public void clear() {
1028 map.clear();
1029 }
1030
1031 @Override
1032 public Set<K> keySet() {
1033 return map.keySet();
1034 }
1035
1036 @Override
1037 public Collection<V> values() {
1038 return map.values();
1039 }
1040
1041 @Override
1042 public Set<Entry<K, V>> entries() {
1043 return map.entrySet();
1044 }
1045
1046 @Override
1047 Iterator<Entry<K, V>> entryIterator() {
1048 return map.entrySet().iterator();
1049 }
1050
1051 @Override
1052 Map<K, Collection<V>> createAsMap() {
1053 return new AsMap<K, V>(this);
1054 }
1055
1056 @Override public int hashCode() {
1057 return map.hashCode();
1058 }
1059
1060 private static final long serialVersionUID = 7845222491160860175L;
1061 }
1062
1063 /**
1064 * Returns a view of a multimap where each value is transformed by a function.
1065 * All other properties of the multimap, such as iteration order, are left
1066 * intact. For example, the code: <pre> {@code
1067 *
1068 * Multimap<String, Integer> multimap =
1069 * ImmutableSetMultimap.of("a", 2, "b", -3, "b", -3, "a", 4, "c", 6);
1070 * Function<Integer, String> square = new Function<Integer, String>() {
1071 * public String apply(Integer in) {
1072 * return Integer.toString(in * in);
1073 * }
1074 * };
1075 * Multimap<String, String> transformed =
1076 * Multimaps.transformValues(multimap, square);
1077 * System.out.println(transformed);}</pre>
1078 *
1079 * ... prints {@code {a=[4, 16], b=[9, 9], c=[36]}}.
1080 *
1081 * <p>Changes in the underlying multimap are reflected in this view.
1082 * Conversely, this view supports removal operations, and these are reflected
1083 * in the underlying multimap.
1084 *
1085 * <p>It's acceptable for the underlying multimap to contain null keys, and
1086 * even null values provided that the function is capable of accepting null
1087 * input. The transformed multimap might contain null values, if the function
1088 * sometimes gives a null result.
1089 *
1090 * <p>The returned multimap is not thread-safe or serializable, even if the
1091 * underlying multimap is. The {@code equals} and {@code hashCode} methods
1092 * of the returned multimap are meaningless, since there is not a definition
1093 * of {@code equals} or {@code hashCode} for general collections, and
1094 * {@code get()} will return a general {@code Collection} as opposed to a
1095 * {@code List} or a {@code Set}.
1096 *
1097 * <p>The function is applied lazily, invoked when needed. This is necessary
1098 * for the returned multimap to be a view, but it means that the function will
1099 * be applied many times for bulk operations like
1100 * {@link Multimap#containsValue} and {@code Multimap.toString()}. For this to
1101 * perform well, {@code function} should be fast. To avoid lazy evaluation
1102 * when the returned multimap doesn't need to be a view, copy the returned
1103 * multimap into a new multimap of your choosing.
1104 *
1105 * @since 7.0
1106 */
1107 public static <K, V1, V2> Multimap<K, V2> transformValues(
1108 Multimap<K, V1> fromMultimap, final Function<? super V1, V2> function) {
1109 checkNotNull(function);
1110 EntryTransformer<K, V1, V2> transformer = Maps.asEntryTransformer(function);
1111 return transformEntries(fromMultimap, transformer);
1112 }
1113
1114 /**
1115 * Returns a view of a multimap whose values are derived from the original
1116 * multimap's entries. In contrast to {@link #transformValues}, this method's
1117 * entry-transformation logic may depend on the key as well as the value.
1118 *
1119 * <p>All other properties of the transformed multimap, such as iteration
1120 * order, are left intact. For example, the code: <pre> {@code
1121 *
1122 * SetMultimap<String, Integer> multimap =
1123 * ImmutableSetMultimap.of("a", 1, "a", 4, "b", -6);
1124 * EntryTransformer<String, Integer, String> transformer =
1125 * new EntryTransformer<String, Integer, String>() {
1126 * public String transformEntry(String key, Integer value) {
1127 * return (value >= 0) ? key : "no" + key;
1128 * }
1129 * };
1130 * Multimap<String, String> transformed =
1131 * Multimaps.transformEntries(multimap, transformer);
1132 * System.out.println(transformed);}</pre>
1133 *
1134 * ... prints {@code {a=[a, a], b=[nob]}}.
1135 *
1136 * <p>Changes in the underlying multimap are reflected in this view.
1137 * Conversely, this view supports removal operations, and these are reflected
1138 * in the underlying multimap.
1139 *
1140 * <p>It's acceptable for the underlying multimap to contain null keys and
1141 * null values provided that the transformer is capable of accepting null
1142 * inputs. The transformed multimap might contain null values if the
1143 * transformer sometimes gives a null result.
1144 *
1145 * <p>The returned multimap is not thread-safe or serializable, even if the
1146 * underlying multimap is. The {@code equals} and {@code hashCode} methods
1147 * of the returned multimap are meaningless, since there is not a definition
1148 * of {@code equals} or {@code hashCode} for general collections, and
1149 * {@code get()} will return a general {@code Collection} as opposed to a
1150 * {@code List} or a {@code Set}.
1151 *
1152 * <p>The transformer is applied lazily, invoked when needed. This is
1153 * necessary for the returned multimap to be a view, but it means that the
1154 * transformer will be applied many times for bulk operations like {@link
1155 * Multimap#containsValue} and {@link Object#toString}. For this to perform
1156 * well, {@code transformer} should be fast. To avoid lazy evaluation when the
1157 * returned multimap doesn't need to be a view, copy the returned multimap
1158 * into a new multimap of your choosing.
1159 *
1160 * <p><b>Warning:</b> This method assumes that for any instance {@code k} of
1161 * {@code EntryTransformer} key type {@code K}, {@code k.equals(k2)} implies
1162 * that {@code k2} is also of type {@code K}. Using an {@code
1163 * EntryTransformer} key type for which this may not hold, such as {@code
1164 * ArrayList}, may risk a {@code ClassCastException} when calling methods on
1165 * the transformed multimap.
1166 *
1167 * @since 7.0
1168 */
1169 public static <K, V1, V2> Multimap<K, V2> transformEntries(
1170 Multimap<K, V1> fromMap,
1171 EntryTransformer<? super K, ? super V1, V2> transformer) {
1172 return new TransformedEntriesMultimap<K, V1, V2>(fromMap, transformer);
1173 }
1174
1175 private static class TransformedEntriesMultimap<K, V1, V2>
1176 extends AbstractMultimap<K, V2> {
1177 final Multimap<K, V1> fromMultimap;
1178 final EntryTransformer<? super K, ? super V1, V2> transformer;
1179
1180 TransformedEntriesMultimap(Multimap<K, V1> fromMultimap,
1181 final EntryTransformer<? super K, ? super V1, V2> transformer) {
1182 this.fromMultimap = checkNotNull(fromMultimap);
1183 this.transformer = checkNotNull(transformer);
1184 }
1185
1186 Collection<V2> transform(K key, Collection<V1> values) {
1187 Function<? super V1, V2> function =
1188 Maps.asValueToValueFunction(transformer, key);
1189 if (values instanceof List) {
1190 return Lists.transform((List<V1>) values, function);
1191 } else {
1192 return Collections2.transform(values, function);
1193 }
1194 }
1195
1196 @Override
1197 Map<K, Collection<V2>> createAsMap() {
1198 return Maps.transformEntries(fromMultimap.asMap(),
1199 new EntryTransformer<K, Collection<V1>, Collection<V2>>() {
1200 @Override public Collection<V2> transformEntry(
1201 K key, Collection<V1> value) {
1202 return transform(key, value);
1203 }
1204 });
1205 }
1206
1207 @Override public void clear() {
1208 fromMultimap.clear();
1209 }
1210
1211 @Override public boolean containsKey(Object key) {
1212 return fromMultimap.containsKey(key);
1213 }
1214
1215 @Override
1216 Iterator<Entry<K, V2>> entryIterator() {
1217 return Iterators.transform(fromMultimap.entries().iterator(),
1218 Maps.<K, V1, V2>asEntryToEntryFunction(transformer));
1219 }
1220
1221 @Override public Collection<V2> get(final K key) {
1222 return transform(key, fromMultimap.get(key));
1223 }
1224
1225 @Override public boolean isEmpty() {
1226 return fromMultimap.isEmpty();
1227 }
1228
1229 @Override public Set<K> keySet() {
1230 return fromMultimap.keySet();
1231 }
1232
1233 @Override public Multiset<K> keys() {
1234 return fromMultimap.keys();
1235 }
1236
1237 @Override public boolean put(K key, V2 value) {
1238 throw new UnsupportedOperationException();
1239 }
1240
1241 @Override public boolean putAll(K key, Iterable<? extends V2> values) {
1242 throw new UnsupportedOperationException();
1243 }
1244
1245 @Override public boolean putAll(
1246 Multimap<? extends K, ? extends V2> multimap) {
1247 throw new UnsupportedOperationException();
1248 }
1249
1250 @SuppressWarnings("unchecked")
1251 @Override public boolean remove(Object key, Object value) {
1252 return get((K) key).remove(value);
1253 }
1254
1255 @SuppressWarnings("unchecked")
1256 @Override public Collection<V2> removeAll(Object key) {
1257 return transform((K) key, fromMultimap.removeAll(key));
1258 }
1259
1260 @Override public Collection<V2> replaceValues(
1261 K key, Iterable<? extends V2> values) {
1262 throw new UnsupportedOperationException();
1263 }
1264
1265 @Override public int size() {
1266 return fromMultimap.size();
1267 }
1268
1269 @Override
1270 Collection<V2> createValues() {
1271 return Collections2.transform(
1272 fromMultimap.entries(), Maps.<K, V1, V2>asEntryToValueFunction(transformer));
1273 }
1274 }
1275
1276 /**
1277 * Returns a view of a {@code ListMultimap} where each value is transformed by
1278 * a function. All other properties of the multimap, such as iteration order,
1279 * are left intact. For example, the code: <pre> {@code
1280 *
1281 * ListMultimap<String, Integer> multimap
1282 * = ImmutableListMultimap.of("a", 4, "a", 16, "b", 9);
1283 * Function<Integer, Double> sqrt =
1284 * new Function<Integer, Double>() {
1285 * public Double apply(Integer in) {
1286 * return Math.sqrt((int) in);
1287 * }
1288 * };
1289 * ListMultimap<String, Double> transformed = Multimaps.transformValues(map,
1290 * sqrt);
1291 * System.out.println(transformed);}</pre>
1292 *
1293 * ... prints {@code {a=[2.0, 4.0], b=[3.0]}}.
1294 *
1295 * <p>Changes in the underlying multimap are reflected in this view.
1296 * Conversely, this view supports removal operations, and these are reflected
1297 * in the underlying multimap.
1298 *
1299 * <p>It's acceptable for the underlying multimap to contain null keys, and
1300 * even null values provided that the function is capable of accepting null
1301 * input. The transformed multimap might contain null values, if the function
1302 * sometimes gives a null result.
1303 *
1304 * <p>The returned multimap is not thread-safe or serializable, even if the
1305 * underlying multimap is.
1306 *
1307 * <p>The function is applied lazily, invoked when needed. This is necessary
1308 * for the returned multimap to be a view, but it means that the function will
1309 * be applied many times for bulk operations like
1310 * {@link Multimap#containsValue} and {@code Multimap.toString()}. For this to
1311 * perform well, {@code function} should be fast. To avoid lazy evaluation
1312 * when the returned multimap doesn't need to be a view, copy the returned
1313 * multimap into a new multimap of your choosing.
1314 *
1315 * @since 7.0
1316 */
1317 public static <K, V1, V2> ListMultimap<K, V2> transformValues(
1318 ListMultimap<K, V1> fromMultimap,
1319 final Function<? super V1, V2> function) {
1320 checkNotNull(function);
1321 EntryTransformer<K, V1, V2> transformer = Maps.asEntryTransformer(function);
1322 return transformEntries(fromMultimap, transformer);
1323 }
1324
1325 /**
1326 * Returns a view of a {@code ListMultimap} whose values are derived from the
1327 * original multimap's entries. In contrast to
1328 * {@link #transformValues(ListMultimap, Function)}, this method's
1329 * entry-transformation logic may depend on the key as well as the value.
1330 *
1331 * <p>All other properties of the transformed multimap, such as iteration
1332 * order, are left intact. For example, the code: <pre> {@code
1333 *
1334 * Multimap<String, Integer> multimap =
1335 * ImmutableMultimap.of("a", 1, "a", 4, "b", 6);
1336 * EntryTransformer<String, Integer, String> transformer =
1337 * new EntryTransformer<String, Integer, String>() {
1338 * public String transformEntry(String key, Integer value) {
1339 * return key + value;
1340 * }
1341 * };
1342 * Multimap<String, String> transformed =
1343 * Multimaps.transformEntries(multimap, transformer);
1344 * System.out.println(transformed);}</pre>
1345 *
1346 * ... prints {@code {"a"=["a1", "a4"], "b"=["b6"]}}.
1347 *
1348 * <p>Changes in the underlying multimap are reflected in this view.
1349 * Conversely, this view supports removal operations, and these are reflected
1350 * in the underlying multimap.
1351 *
1352 * <p>It's acceptable for the underlying multimap to contain null keys and
1353 * null values provided that the transformer is capable of accepting null
1354 * inputs. The transformed multimap might contain null values if the
1355 * transformer sometimes gives a null result.
1356 *
1357 * <p>The returned multimap is not thread-safe or serializable, even if the
1358 * underlying multimap is.
1359 *
1360 * <p>The transformer is applied lazily, invoked when needed. This is
1361 * necessary for the returned multimap to be a view, but it means that the
1362 * transformer will be applied many times for bulk operations like {@link
1363 * Multimap#containsValue} and {@link Object#toString}. For this to perform
1364 * well, {@code transformer} should be fast. To avoid lazy evaluation when the
1365 * returned multimap doesn't need to be a view, copy the returned multimap
1366 * into a new multimap of your choosing.
1367 *
1368 * <p><b>Warning:</b> This method assumes that for any instance {@code k} of
1369 * {@code EntryTransformer} key type {@code K}, {@code k.equals(k2)} implies
1370 * that {@code k2} is also of type {@code K}. Using an {@code
1371 * EntryTransformer} key type for which this may not hold, such as {@code
1372 * ArrayList}, may risk a {@code ClassCastException} when calling methods on
1373 * the transformed multimap.
1374 *
1375 * @since 7.0
1376 */
1377 public static <K, V1, V2> ListMultimap<K, V2> transformEntries(
1378 ListMultimap<K, V1> fromMap,
1379 EntryTransformer<? super K, ? super V1, V2> transformer) {
1380 return new TransformedEntriesListMultimap<K, V1, V2>(fromMap, transformer);
1381 }
1382
1383 private static final class TransformedEntriesListMultimap<K, V1, V2>
1384 extends TransformedEntriesMultimap<K, V1, V2>
1385 implements ListMultimap<K, V2> {
1386
1387 TransformedEntriesListMultimap(ListMultimap<K, V1> fromMultimap,
1388 EntryTransformer<? super K, ? super V1, V2> transformer) {
1389 super(fromMultimap, transformer);
1390 }
1391
1392 @Override List<V2> transform(K key, Collection<V1> values) {
1393 return Lists.transform((List<V1>) values, Maps.asValueToValueFunction(transformer, key));
1394 }
1395
1396 @Override public List<V2> get(K key) {
1397 return transform(key, fromMultimap.get(key));
1398 }
1399
1400 @SuppressWarnings("unchecked")
1401 @Override public List<V2> removeAll(Object key) {
1402 return transform((K) key, fromMultimap.removeAll(key));
1403 }
1404
1405 @Override public List<V2> replaceValues(
1406 K key, Iterable<? extends V2> values) {
1407 throw new UnsupportedOperationException();
1408 }
1409 }
1410
1411 /**
1412 * Creates an index {@code ImmutableListMultimap} that contains the results of
1413 * applying a specified function to each item in an {@code Iterable} of
1414 * values. Each value will be stored as a value in the resulting multimap,
1415 * yielding a multimap with the same size as the input iterable. The key used
1416 * to store that value in the multimap will be the result of calling the
1417 * function on that value. The resulting multimap is created as an immutable
1418 * snapshot. In the returned multimap, keys appear in the order they are first
1419 * encountered, and the values corresponding to each key appear in the same
1420 * order as they are encountered.
1421 *
1422 * <p>For example, <pre> {@code
1423 *
1424 * List<String> badGuys =
1425 * Arrays.asList("Inky", "Blinky", "Pinky", "Pinky", "Clyde");
1426 * Function<String, Integer> stringLengthFunction = ...;
1427 * Multimap<Integer, String> index =
1428 * Multimaps.index(badGuys, stringLengthFunction);
1429 * System.out.println(index);}</pre>
1430 *
1431 * <p>prints <pre> {@code
1432 *
1433 * {4=[Inky], 6=[Blinky], 5=[Pinky, Pinky, Clyde]}}</pre>
1434 *
1435 * <p>The returned multimap is serializable if its keys and values are all
1436 * serializable.
1437 *
1438 * @param values the values to use when constructing the {@code
1439 * ImmutableListMultimap}
1440 * @param keyFunction the function used to produce the key for each value
1441 * @return {@code ImmutableListMultimap} mapping the result of evaluating the
1442 * function {@code keyFunction} on each value in the input collection to
1443 * that value
1444 * @throws NullPointerException if any of the following cases is true:
1445 * <ul>
1446 * <li>{@code values} is null
1447 * <li>{@code keyFunction} is null
1448 * <li>An element in {@code values} is null
1449 * <li>{@code keyFunction} returns {@code null} for any element of {@code
1450 * values}
1451 * </ul>
1452 */
1453 public static <K, V> ImmutableListMultimap<K, V> index(
1454 Iterable<V> values, Function<? super V, K> keyFunction) {
1455 return index(values.iterator(), keyFunction);
1456 }
1457
1458 /**
1459 * Creates an index {@code ImmutableListMultimap} that contains the results of
1460 * applying a specified function to each item in an {@code Iterator} of
1461 * values. Each value will be stored as a value in the resulting multimap,
1462 * yielding a multimap with the same size as the input iterator. The key used
1463 * to store that value in the multimap will be the result of calling the
1464 * function on that value. The resulting multimap is created as an immutable
1465 * snapshot. In the returned multimap, keys appear in the order they are first
1466 * encountered, and the values corresponding to each key appear in the same
1467 * order as they are encountered.
1468 *
1469 * <p>For example, <pre> {@code
1470 *
1471 * List<String> badGuys =
1472 * Arrays.asList("Inky", "Blinky", "Pinky", "Pinky", "Clyde");
1473 * Function<String, Integer> stringLengthFunction = ...;
1474 * Multimap<Integer, String> index =
1475 * Multimaps.index(badGuys.iterator(), stringLengthFunction);
1476 * System.out.println(index);}</pre>
1477 *
1478 * <p>prints <pre> {@code
1479 *
1480 * {4=[Inky], 6=[Blinky], 5=[Pinky, Pinky, Clyde]}}</pre>
1481 *
1482 * <p>The returned multimap is serializable if its keys and values are all
1483 * serializable.
1484 *
1485 * @param values the values to use when constructing the {@code
1486 * ImmutableListMultimap}
1487 * @param keyFunction the function used to produce the key for each value
1488 * @return {@code ImmutableListMultimap} mapping the result of evaluating the
1489 * function {@code keyFunction} on each value in the input collection to
1490 * that value
1491 * @throws NullPointerException if any of the following cases is true:
1492 * <ul>
1493 * <li>{@code values} is null
1494 * <li>{@code keyFunction} is null
1495 * <li>An element in {@code values} is null
1496 * <li>{@code keyFunction} returns {@code null} for any element of {@code
1497 * values}
1498 * </ul>
1499 * @since 10.0
1500 */
1501 public static <K, V> ImmutableListMultimap<K, V> index(
1502 Iterator<V> values, Function<? super V, K> keyFunction) {
1503 checkNotNull(keyFunction);
1504 ImmutableListMultimap.Builder<K, V> builder
1505 = ImmutableListMultimap.builder();
1506 while (values.hasNext()) {
1507 V value = values.next();
1508 checkNotNull(value, values);
1509 builder.put(keyFunction.apply(value), value);
1510 }
1511 return builder.build();
1512 }
1513
1514 static class Keys<K, V> extends AbstractMultiset<K> {
1515 final Multimap<K, V> multimap;
1516
1517 Keys(Multimap<K, V> multimap) {
1518 this.multimap = multimap;
1519 }
1520
1521 @Override Iterator<Multiset.Entry<K>> entryIterator() {
1522 return new TransformedIterator<Map.Entry<K, Collection<V>>, Multiset.Entry<K>>(
1523 multimap.asMap().entrySet().iterator()) {
1524 @Override
1525 Multiset.Entry<K> transform(
1526 final Map.Entry<K, Collection<V>> backingEntry) {
1527 return new Multisets.AbstractEntry<K>() {
1528 @Override
1529 public K getElement() {
1530 return backingEntry.getKey();
1531 }
1532
1533 @Override
1534 public int getCount() {
1535 return backingEntry.getValue().size();
1536 }
1537 };
1538 }
1539 };
1540 }
1541
1542 @Override int distinctElements() {
1543 return multimap.asMap().size();
1544 }
1545
1546 @Override Set<Multiset.Entry<K>> createEntrySet() {
1547 return new KeysEntrySet();
1548 }
1549
1550 class KeysEntrySet extends Multisets.EntrySet<K> {
1551 @Override Multiset<K> multiset() {
1552 return Keys.this;
1553 }
1554
1555 @Override public Iterator<Multiset.Entry<K>> iterator() {
1556 return entryIterator();
1557 }
1558
1559 @Override public int size() {
1560 return distinctElements();
1561 }
1562
1563 @Override public boolean isEmpty() {
1564 return multimap.isEmpty();
1565 }
1566
1567 @Override public boolean contains(@Nullable Object o) {
1568 if (o instanceof Multiset.Entry) {
1569 Multiset.Entry<?> entry = (Multiset.Entry<?>) o;
1570 Collection<V> collection = multimap.asMap().get(entry.getElement());
1571 return collection != null && collection.size() == entry.getCount();
1572 }
1573 return false;
1574 }
1575
1576 @Override public boolean remove(@Nullable Object o) {
1577 if (o instanceof Multiset.Entry) {
1578 Multiset.Entry<?> entry = (Multiset.Entry<?>) o;
1579 Collection<V> collection = multimap.asMap().get(entry.getElement());
1580 if (collection != null && collection.size() == entry.getCount()) {
1581 collection.clear();
1582 return true;
1583 }
1584 }
1585 return false;
1586 }
1587 }
1588
1589 @Override public boolean contains(@Nullable Object element) {
1590 return multimap.containsKey(element);
1591 }
1592
1593 @Override public Iterator<K> iterator() {
1594 return Maps.keyIterator(multimap.entries().iterator());
1595 }
1596
1597 @Override public int count(@Nullable Object element) {
1598 Collection<V> values = Maps.safeGet(multimap.asMap(), element);
1599 return (values == null) ? 0 : values.size();
1600 }
1601
1602 @Override public int remove(@Nullable Object element, int occurrences) {
1603 checkNonnegative(occurrences, "occurrences");
1604 if (occurrences == 0) {
1605 return count(element);
1606 }
1607
1608 Collection<V> values = Maps.safeGet(multimap.asMap(), element);
1609
1610 if (values == null) {
1611 return 0;
1612 }
1613
1614 int oldCount = values.size();
1615 if (occurrences >= oldCount) {
1616 values.clear();
1617 } else {
1618 Iterator<V> iterator = values.iterator();
1619 for (int i = 0; i < occurrences; i++) {
1620 iterator.next();
1621 iterator.remove();
1622 }
1623 }
1624 return oldCount;
1625 }
1626
1627 @Override public void clear() {
1628 multimap.clear();
1629 }
1630
1631 @Override public Set<K> elementSet() {
1632 return multimap.keySet();
1633 }
1634 }
1635
1636 /**
1637 * A skeleton implementation of {@link Multimap#entries()}.
1638 */
1639 abstract static class Entries<K, V> extends
1640 AbstractCollection<Map.Entry<K, V>> {
1641 abstract Multimap<K, V> multimap();
1642
1643 @Override public int size() {
1644 return multimap().size();
1645 }
1646
1647 @Override public boolean contains(@Nullable Object o) {
1648 if (o instanceof Map.Entry) {
1649 Map.Entry<?, ?> entry = (Map.Entry<?, ?>) o;
1650 return multimap().containsEntry(entry.getKey(), entry.getValue());
1651 }
1652 return false;
1653 }
1654
1655 @Override public boolean remove(@Nullable Object o) {
1656 if (o instanceof Map.Entry) {
1657 Map.Entry<?, ?> entry = (Map.Entry<?, ?>) o;
1658 return multimap().remove(entry.getKey(), entry.getValue());
1659 }
1660 return false;
1661 }
1662
1663 @Override public void clear() {
1664 multimap().clear();
1665 }
1666 }
1667
1668 /**
1669 * A skeleton implementation of {@link Multimap#asMap()}.
1670 */
1671 static final class AsMap<K, V> extends
1672 Maps.ImprovedAbstractMap<K, Collection<V>> {
1673 private final Multimap<K, V> multimap;
1674
1675 AsMap(Multimap<K, V> multimap) {
1676 this.multimap = checkNotNull(multimap);
1677 }
1678
1679 @Override public int size() {
1680 return multimap.keySet().size();
1681 }
1682
1683 @Override protected Set<Entry<K, Collection<V>>> createEntrySet() {
1684 return new EntrySet();
1685 }
1686
1687 void removeValuesForKey(Object key) {
1688 multimap.keySet().remove(key);
1689 }
1690
1691 class EntrySet extends Maps.EntrySet<K, Collection<V>> {
1692 @Override Map<K, Collection<V>> map() {
1693 return AsMap.this;
1694 }
1695
1696 @Override public Iterator<Entry<K, Collection<V>>> iterator() {
1697 return Maps.asMapEntryIterator(multimap.keySet(), new Function<K, Collection<V>>() {
1698 @Override
1699 public Collection<V> apply(K key) {
1700 return multimap.get(key);
1701 }
1702 });
1703 }
1704
1705 @Override public boolean remove(Object o) {
1706 if (!contains(o)) {
1707 return false;
1708 }
1709 Map.Entry<?, ?> entry = (Map.Entry<?, ?>) o;
1710 removeValuesForKey(entry.getKey());
1711 return true;
1712 }
1713 }
1714
1715 @SuppressWarnings("unchecked")
1716 @Override public Collection<V> get(Object key) {
1717 return containsKey(key) ? multimap.get((K) key) : null;
1718 }
1719
1720 @Override public Collection<V> remove(Object key) {
1721 return containsKey(key) ? multimap.removeAll(key) : null;
1722 }
1723
1724 @Override public Set<K> keySet() {
1725 return multimap.keySet();
1726 }
1727
1728 @Override public boolean isEmpty() {
1729 return multimap.isEmpty();
1730 }
1731
1732 @Override public boolean containsKey(Object key) {
1733 return multimap.containsKey(key);
1734 }
1735
1736 @Override public void clear() {
1737 multimap.clear();
1738 }
1739 }
1740
1741 /**
1742 * Returns a multimap containing the mappings in {@code unfiltered} whose keys
1743 * satisfy a predicate. The returned multimap is a live view of
1744 * {@code unfiltered}; changes to one affect the other.
1745 *
1746 * <p>The resulting multimap's views have iterators that don't support
1747 * {@code remove()}, but all other methods are supported by the multimap and
1748 * its views. When adding a key that doesn't satisfy the predicate, the
1749 * multimap's {@code put()}, {@code putAll()}, and {@code replaceValues()}
1750 * methods throw an {@link IllegalArgumentException}.
1751 *
1752 * <p>When methods such as {@code removeAll()} and {@code clear()} are called on
1753 * the filtered multimap or its views, only mappings whose keys satisfy the
1754 * filter will be removed from the underlying multimap.
1755 *
1756 * <p>The returned multimap isn't threadsafe or serializable, even if
1757 * {@code unfiltered} is.
1758 *
1759 * <p>Many of the filtered multimap's methods, such as {@code size()}, iterate
1760 * across every key/value mapping in the underlying multimap and determine
1761 * which satisfy the filter. When a live view is <i>not</i> needed, it may be
1762 * faster to copy the filtered multimap and use the copy.
1763 *
1764 * <p><b>Warning:</b> {@code keyPredicate} must be <i>consistent with equals</i>,
1765 * as documented at {@link Predicate#apply}. Do not provide a predicate such
1766 * as {@code Predicates.instanceOf(ArrayList.class)}, which is inconsistent
1767 * with equals.
1768 *
1769 * @since 11.0
1770 */
1771 public static <K, V> Multimap<K, V> filterKeys(
1772 Multimap<K, V> unfiltered, final Predicate<? super K> keyPredicate) {
1773 if (unfiltered instanceof SetMultimap) {
1774 return filterKeys((SetMultimap<K, V>) unfiltered, keyPredicate);
1775 } else if (unfiltered instanceof ListMultimap) {
1776 return filterKeys((ListMultimap<K, V>) unfiltered, keyPredicate);
1777 } else if (unfiltered instanceof FilteredKeyMultimap) {
1778 FilteredKeyMultimap<K, V> prev = (FilteredKeyMultimap<K, V>) unfiltered;
1779 return new FilteredKeyMultimap<K, V>(prev.unfiltered,
1780 Predicates.and(prev.keyPredicate, keyPredicate));
1781 } else if (unfiltered instanceof FilteredMultimap) {
1782 FilteredMultimap<K, V> prev = (FilteredMultimap<K, V>) unfiltered;
1783 return filterFiltered(prev, Maps.<K>keyPredicateOnEntries(keyPredicate));
1784 } else {
1785 return new FilteredKeyMultimap<K, V>(unfiltered, keyPredicate);
1786 }
1787 }
1788
1789 /**
1790 * Returns a multimap containing the mappings in {@code unfiltered} whose keys
1791 * satisfy a predicate. The returned multimap is a live view of
1792 * {@code unfiltered}; changes to one affect the other.
1793 *
1794 * <p>The resulting multimap's views have iterators that don't support
1795 * {@code remove()}, but all other methods are supported by the multimap and
1796 * its views. When adding a key that doesn't satisfy the predicate, the
1797 * multimap's {@code put()}, {@code putAll()}, and {@code replaceValues()}
1798 * methods throw an {@link IllegalArgumentException}.
1799 *
1800 * <p>When methods such as {@code removeAll()} and {@code clear()} are called on
1801 * the filtered multimap or its views, only mappings whose keys satisfy the
1802 * filter will be removed from the underlying multimap.
1803 *
1804 * <p>The returned multimap isn't threadsafe or serializable, even if
1805 * {@code unfiltered} is.
1806 *
1807 * <p>Many of the filtered multimap's methods, such as {@code size()}, iterate
1808 * across every key/value mapping in the underlying multimap and determine
1809 * which satisfy the filter. When a live view is <i>not</i> needed, it may be
1810 * faster to copy the filtered multimap and use the copy.
1811 *
1812 * <p><b>Warning:</b> {@code keyPredicate} must be <i>consistent with equals</i>,
1813 * as documented at {@link Predicate#apply}. Do not provide a predicate such
1814 * as {@code Predicates.instanceOf(ArrayList.class)}, which is inconsistent
1815 * with equals.
1816 *
1817 * @since 14.0
1818 */
1819 public static <K, V> SetMultimap<K, V> filterKeys(
1820 SetMultimap<K, V> unfiltered, final Predicate<? super K> keyPredicate) {
1821 if (unfiltered instanceof FilteredKeySetMultimap) {
1822 FilteredKeySetMultimap<K, V> prev = (FilteredKeySetMultimap<K, V>) unfiltered;
1823 return new FilteredKeySetMultimap<K, V>(prev.unfiltered(),
1824 Predicates.and(prev.keyPredicate, keyPredicate));
1825 } else if (unfiltered instanceof FilteredSetMultimap) {
1826 FilteredSetMultimap<K, V> prev = (FilteredSetMultimap<K, V>) unfiltered;
1827 return filterFiltered(prev, Maps.<K>keyPredicateOnEntries(keyPredicate));
1828 } else {
1829 return new FilteredKeySetMultimap<K, V>(unfiltered, keyPredicate);
1830 }
1831 }
1832
1833 /**
1834 * Returns a multimap containing the mappings in {@code unfiltered} whose keys
1835 * satisfy a predicate. The returned multimap is a live view of
1836 * {@code unfiltered}; changes to one affect the other.
1837 *
1838 * <p>The resulting multimap's views have iterators that don't support
1839 * {@code remove()}, but all other methods are supported by the multimap and
1840 * its views. When adding a key that doesn't satisfy the predicate, the
1841 * multimap's {@code put()}, {@code putAll()}, and {@code replaceValues()}
1842 * methods throw an {@link IllegalArgumentException}.
1843 *
1844 * <p>When methods such as {@code removeAll()} and {@code clear()} are called on
1845 * the filtered multimap or its views, only mappings whose keys satisfy the
1846 * filter will be removed from the underlying multimap.
1847 *
1848 * <p>The returned multimap isn't threadsafe or serializable, even if
1849 * {@code unfiltered} is.
1850 *
1851 * <p>Many of the filtered multimap's methods, such as {@code size()}, iterate
1852 * across every key/value mapping in the underlying multimap and determine
1853 * which satisfy the filter. When a live view is <i>not</i> needed, it may be
1854 * faster to copy the filtered multimap and use the copy.
1855 *
1856 * <p><b>Warning:</b> {@code keyPredicate} must be <i>consistent with equals</i>,
1857 * as documented at {@link Predicate#apply}. Do not provide a predicate such
1858 * as {@code Predicates.instanceOf(ArrayList.class)}, which is inconsistent
1859 * with equals.
1860 *
1861 * @since 14.0
1862 */
1863 public static <K, V> ListMultimap<K, V> filterKeys(
1864 ListMultimap<K, V> unfiltered, final Predicate<? super K> keyPredicate) {
1865 if (unfiltered instanceof FilteredKeyListMultimap) {
1866 FilteredKeyListMultimap<K, V> prev = (FilteredKeyListMultimap<K, V>) unfiltered;
1867 return new FilteredKeyListMultimap<K, V>(prev.unfiltered(),
1868 Predicates.and(prev.keyPredicate, keyPredicate));
1869 } else {
1870 return new FilteredKeyListMultimap<K, V>(unfiltered, keyPredicate);
1871 }
1872 }
1873
1874 /**
1875 * Returns a multimap containing the mappings in {@code unfiltered} whose values
1876 * satisfy a predicate. The returned multimap is a live view of
1877 * {@code unfiltered}; changes to one affect the other.
1878 *
1879 * <p>The resulting multimap's views have iterators that don't support
1880 * {@code remove()}, but all other methods are supported by the multimap and
1881 * its views. When adding a value that doesn't satisfy the predicate, the
1882 * multimap's {@code put()}, {@code putAll()}, and {@code replaceValues()}
1883 * methods throw an {@link IllegalArgumentException}.
1884 *
1885 * <p>When methods such as {@code removeAll()} and {@code clear()} are called on
1886 * the filtered multimap or its views, only mappings whose value satisfy the
1887 * filter will be removed from the underlying multimap.
1888 *
1889 * <p>The returned multimap isn't threadsafe or serializable, even if
1890 * {@code unfiltered} is.
1891 *
1892 * <p>Many of the filtered multimap's methods, such as {@code size()}, iterate
1893 * across every key/value mapping in the underlying multimap and determine
1894 * which satisfy the filter. When a live view is <i>not</i> needed, it may be
1895 * faster to copy the filtered multimap and use the copy.
1896 *
1897 * <p><b>Warning:</b> {@code valuePredicate} must be <i>consistent with
1898 * equals</i>, as documented at {@link Predicate#apply}. Do not provide a
1899 * predicate such as {@code Predicates.instanceOf(ArrayList.class)}, which is
1900 * inconsistent with equals.
1901 *
1902 * @since 11.0
1903 */
1904 public static <K, V> Multimap<K, V> filterValues(
1905 Multimap<K, V> unfiltered, final Predicate<? super V> valuePredicate) {
1906 return filterEntries(unfiltered, Maps.<V>valuePredicateOnEntries(valuePredicate));
1907 }
1908
1909 /**
1910 * Returns a multimap containing the mappings in {@code unfiltered} whose values
1911 * satisfy a predicate. The returned multimap is a live view of
1912 * {@code unfiltered}; changes to one affect the other.
1913 *
1914 * <p>The resulting multimap's views have iterators that don't support
1915 * {@code remove()}, but all other methods are supported by the multimap and
1916 * its views. When adding a value that doesn't satisfy the predicate, the
1917 * multimap's {@code put()}, {@code putAll()}, and {@code replaceValues()}
1918 * methods throw an {@link IllegalArgumentException}.
1919 *
1920 * <p>When methods such as {@code removeAll()} and {@code clear()} are called on
1921 * the filtered multimap or its views, only mappings whose value satisfy the
1922 * filter will be removed from the underlying multimap.
1923 *
1924 * <p>The returned multimap isn't threadsafe or serializable, even if
1925 * {@code unfiltered} is.
1926 *
1927 * <p>Many of the filtered multimap's methods, such as {@code size()}, iterate
1928 * across every key/value mapping in the underlying multimap and determine
1929 * which satisfy the filter. When a live view is <i>not</i> needed, it may be
1930 * faster to copy the filtered multimap and use the copy.
1931 *
1932 * <p><b>Warning:</b> {@code valuePredicate} must be <i>consistent with
1933 * equals</i>, as documented at {@link Predicate#apply}. Do not provide a
1934 * predicate such as {@code Predicates.instanceOf(ArrayList.class)}, which is
1935 * inconsistent with equals.
1936 *
1937 * @since 14.0
1938 */
1939 public static <K, V> SetMultimap<K, V> filterValues(
1940 SetMultimap<K, V> unfiltered, final Predicate<? super V> valuePredicate) {
1941 return filterEntries(unfiltered, Maps.<V>valuePredicateOnEntries(valuePredicate));
1942 }
1943
1944 /**
1945 * Returns a multimap containing the mappings in {@code unfiltered} that
1946 * satisfy a predicate. The returned multimap is a live view of
1947 * {@code unfiltered}; changes to one affect the other.
1948 *
1949 * <p>The resulting multimap's views have iterators that don't support
1950 * {@code remove()}, but all other methods are supported by the multimap and
1951 * its views. When adding a key/value pair that doesn't satisfy the predicate,
1952 * multimap's {@code put()}, {@code putAll()}, and {@code replaceValues()}
1953 * methods throw an {@link IllegalArgumentException}.
1954 *
1955 * <p>When methods such as {@code removeAll()} and {@code clear()} are called on
1956 * the filtered multimap or its views, only mappings whose keys satisfy the
1957 * filter will be removed from the underlying multimap.
1958 *
1959 * <p>The returned multimap isn't threadsafe or serializable, even if
1960 * {@code unfiltered} is.
1961 *
1962 * <p>Many of the filtered multimap's methods, such as {@code size()}, iterate
1963 * across every key/value mapping in the underlying multimap and determine
1964 * which satisfy the filter. When a live view is <i>not</i> needed, it may be
1965 * faster to copy the filtered multimap and use the copy.
1966 *
1967 * <p><b>Warning:</b> {@code entryPredicate} must be <i>consistent with
1968 * equals</i>, as documented at {@link Predicate#apply}.
1969 *
1970 * @since 11.0
1971 */
1972 public static <K, V> Multimap<K, V> filterEntries(
1973 Multimap<K, V> unfiltered, Predicate<? super Entry<K, V>> entryPredicate) {
1974 checkNotNull(entryPredicate);
1975 if (unfiltered instanceof SetMultimap) {
1976 return filterEntries((SetMultimap<K, V>) unfiltered, entryPredicate);
1977 }
1978 return (unfiltered instanceof FilteredMultimap)
1979 ? filterFiltered((FilteredMultimap<K, V>) unfiltered, entryPredicate)
1980 : new FilteredEntryMultimap<K, V>(checkNotNull(unfiltered), entryPredicate);
1981 }
1982
1983 /**
1984 * Returns a multimap containing the mappings in {@code unfiltered} that
1985 * satisfy a predicate. The returned multimap is a live view of
1986 * {@code unfiltered}; changes to one affect the other.
1987 *
1988 * <p>The resulting multimap's views have iterators that don't support
1989 * {@code remove()}, but all other methods are supported by the multimap and
1990 * its views. When adding a key/value pair that doesn't satisfy the predicate,
1991 * multimap's {@code put()}, {@code putAll()}, and {@code replaceValues()}
1992 * methods throw an {@link IllegalArgumentException}.
1993 *
1994 * <p>When methods such as {@code removeAll()} and {@code clear()} are called on
1995 * the filtered multimap or its views, only mappings whose keys satisfy the
1996 * filter will be removed from the underlying multimap.
1997 *
1998 * <p>The returned multimap isn't threadsafe or serializable, even if
1999 * {@code unfiltered} is.
2000 *
2001 * <p>Many of the filtered multimap's methods, such as {@code size()}, iterate
2002 * across every key/value mapping in the underlying multimap and determine
2003 * which satisfy the filter. When a live view is <i>not</i> needed, it may be
2004 * faster to copy the filtered multimap and use the copy.
2005 *
2006 * <p><b>Warning:</b> {@code entryPredicate} must be <i>consistent with
2007 * equals</i>, as documented at {@link Predicate#apply}.
2008 *
2009 * @since 14.0
2010 */
2011 public static <K, V> SetMultimap<K, V> filterEntries(
2012 SetMultimap<K, V> unfiltered, Predicate<? super Entry<K, V>> entryPredicate) {
2013 checkNotNull(entryPredicate);
2014 return (unfiltered instanceof FilteredSetMultimap)
2015 ? filterFiltered((FilteredSetMultimap<K, V>) unfiltered, entryPredicate)
2016 : new FilteredEntrySetMultimap<K, V>(checkNotNull(unfiltered), entryPredicate);
2017 }
2018
2019 /**
2020 * Support removal operations when filtering a filtered multimap. Since a
2021 * filtered multimap has iterators that don't support remove, passing one to
2022 * the FilteredEntryMultimap constructor would lead to a multimap whose removal
2023 * operations would fail. This method combines the predicates to avoid that
2024 * problem.
2025 */
2026 private static <K, V> Multimap<K, V> filterFiltered(FilteredMultimap<K, V> multimap,
2027 Predicate<? super Entry<K, V>> entryPredicate) {
2028 Predicate<Entry<K, V>> predicate
2029 = Predicates.and(multimap.entryPredicate(), entryPredicate);
2030 return new FilteredEntryMultimap<K, V>(multimap.unfiltered(), predicate);
2031 }
2032
2033 /**
2034 * Support removal operations when filtering a filtered multimap. Since a filtered multimap has
2035 * iterators that don't support remove, passing one to the FilteredEntryMultimap constructor would
2036 * lead to a multimap whose removal operations would fail. This method combines the predicates to
2037 * avoid that problem.
2038 */
2039 private static <K, V> SetMultimap<K, V> filterFiltered(
2040 FilteredSetMultimap<K, V> multimap,
2041 Predicate<? super Entry<K, V>> entryPredicate) {
2042 Predicate<Entry<K, V>> predicate
2043 = Predicates.and(multimap.entryPredicate(), entryPredicate);
2044 return new FilteredEntrySetMultimap<K, V>(multimap.unfiltered(), predicate);
2045 }
2046
2047 static boolean equalsImpl(Multimap<?, ?> multimap, @Nullable Object object) {
2048 if (object == multimap) {
2049 return true;
2050 }
2051 if (object instanceof Multimap) {
2052 Multimap<?, ?> that = (Multimap<?, ?>) object;
2053 return multimap.asMap().equals(that.asMap());
2054 }
2055 return false;
2056 }
2057
2058 // TODO(jlevy): Create methods that filter a SortedSetMultimap.
2059 }